#include "Spi_Dev_Management/Spi_Buffer_Manager.h"
#include "rclcpp/rclcpp.hpp"
#include <cstring>

static rclcpp::Logger TRACE = rclcpp::get_logger("Data_Buffer");

Base_Data_Buffer::Base_Data_Buffer(const size_t& data_size)
    : its_using_flag(data_size)
{

}

bool Base_Data_Buffer::vaild_and_set(const std::string& unique_id, const uint16_t& start_position, const size_t& length)
{
    auto data_buffer_it = its_user_group.find(unique_id);
    if(data_buffer_it != its_user_group.end())
    {
        return false;
    }
    else
    {
        for(size_t i = start_position; i < length + start_position; i++)
        {
            if(its_using_flag[i])
            {
                return false;
            }
        }

        for(size_t i = start_position; i < length + start_position; i++)
        {
            if(its_using_flag[i])
            {
                return false;
            }
        }
    }
    return true;
}

Soc_Out_Data_Buffer::Soc_Out_Data_Buffer(const size_t& data_size)
    : Base_Data_Buffer(data_size), its_buffer(data_size)
{
}


bool Soc_Out_Data_Buffer::copy_full_buffer(uint8_t* output, const size_t& size)
{
    std::unique_lock<std::shared_mutex> unique_read_lock(its_shared_mutex);
    if(size != its_buffer.size())
    {
        RCLCPP_ERROR_STREAM(TRACE, "Invaild size, expect : " << its_buffer.size() << "actual : " << size);
        return false;
    }
    else
    {
        memcpy(output, its_buffer.data(), size);
        return true;
    }
}

Soc_In_Data_Buffer::Soc_In_Data_Buffer(const size_t& data_size)
    : Base_Data_Buffer(data_size), its_buffer(data_size)
{

}

bool Soc_In_Data_Buffer::copy_full_buffer(const uint8_t* const input, const size_t& size)
{
    std::unique_lock<std::shared_mutex> unique_read_lock(its_shared_mutex);
    if(size != its_buffer.size())
    {
        // LOG(WARNING) << "Invaild size, expect : " << its_buffer.size() << "actual : " << size;
        return false;
    }
    else
    {
        memcpy(its_buffer.data(), input, size);
        return true;
    }
}

bool Soc_In_Data_Buffer::wait_for_update()
{
    std::unique_lock<std::mutex> lock(its_update_mutex);
    its_update_cond.wait(lock);
    return true;
}

void Soc_In_Data_Buffer::notify_update()
{
    std::unique_lock<std::mutex> lock(its_update_mutex);
    its_update_cond.notify_all();
}
